#ifndef __LOGGER_H__
#define __LOGGER_H__

#include <string>
#include <fstream>
#include <stdexcept>
#include <cstdarg>
#include <iostream>
#include <time.h>
#include <string.h>

#define debug(format, ...) Logger::instance()->log(Logger::DEBUG, __FILE__, __LINE__, format, __VA_ARGS__);
#define info(format, ...) Logger::instance()->log(Logger::INFO, __FILE__, __LINE__, format, __VA_ARGS__);
#define warn(format, ...) Logger::instance()->log(Logger::WARN, __FILE__, __LINE__, format, __VA_ARGS__);
#define error(format, ...) Logger::instance()->log(Logger::ERROR, __FILE__, __LINE__, format, __VA_ARGS__);
#define fatal(format, ...) Logger::instance()->log(Logger::FATAL, __FILE__, __LINE__, format, __VA_ARGS__);

class Logger
{
public:
    enum Level
    {
        DEBUG = 0,
        INFO,
        WARN,
        ERROR,
        FATAL,
        LEVEL_COUNT
    };
    static Logger * instance();
    void open(const std::string & filename);
    void close();
    void log(Level level, const char * file, int line, const char * format, ...);
    void level(Level leve);
    void max(int bytes);

private:
    Logger();
    ~Logger();
    void rotate();

private:
    std::string m_filename;
    std::ofstream m_fout;
    static const char * s_level[LEVEL_COUNT];
    static Logger * m_instance;
    Level m_level;
    int m_len;
    int m_max;
};

#endif
